﻿using System;
using System.Collections.Generic;
using BCCommon;
using BCCommon.Enums;
using BCCommon.PaymentEnums;
using BCDto.Common.Payment.Payment;
using BCDto.Common.Payment.PaymentRecord;
using BCDto.Sim.Admin.Admin;
using BCDto.Website.User;

namespace BCService.Common.Payment.Payment
{
    /// <summary>
    /// 支付渠道
    /// </summary>
    [NonInjection]
    public interface IChannelFactoryService
    {
        /// <summary>
        /// APP类型
        /// </summary>
        SourceAppType AppType { get; set; }

        /// <summary>
        /// 操作系统
        /// </summary>
        SourceOSType OSType { get; set; }

        /// <summary>
        /// 支付渠道类型
        /// </summary>
        PaymentChannelType ChannelType { get; set; }

        /// <summary>
        /// 获取余额
        /// </summary>
        /// <returns></returns>
        decimal? GetBalance(UserDto userDto);
        /// <summary>
        /// 获取多个记录
        /// </summary>
        /// <returns></returns>
        decimal? GetLimit(UserDto userDto);

        /// <summary>
        /// 获取余额
        /// </summary>
        /// <returns></returns>
        decimal? GetAgentBalance(long agentRecordId);
        /// <summary>
        /// 获取多个记录
        /// </summary>
        /// <returns></returns>
        decimal? GetAgentLimit(long agentRecordId);

        /// <summary>
        /// 确认支付--仅在非线上支付和余额时使用
        /// </summary>
        /// <param name="paymentRecordId">支付记录Id</param>
        /// <param name="referenceNumber">订单编号</param>
        /// <param name="password">支付密码</param>
        /// <param name="userDto"></param>
        /// <returns></returns>
        [Obsolete("请使用 TryPay 方法统一验证。")]
        bool ConfirmPayValidation(long paymentRecordId, string referenceNumber, string password, UserDto userDto);

        /// <summary>
        /// 尝试支付。
        /// </summary>
        /// <param name="appType">应用类型。</param>
        /// <param name="orderType">订单类型。</param>
        /// <param name="subject">交易订单标题</param>
        /// <param name="referenceNumber">唯一参考号。</param>
        /// <param name="osType">操作系统。</param>
        /// <param name="deviceType">设备类型。</param>
        /// <param name="deviceId">设备编号。</param>
        /// <param name="parameters">参数。</param>
        /// <param name="amount">支付金额。</param>
        /// <param name="payer">付款方</param>
        /// <param name="userDto"></param>
        /// <returns></returns>
        PaymentDto TryPay(SourceAppType appType, FlowType orderType, string subject, string referenceNumber, SourceOSType osType,
            SourceDeviceType deviceType, string deviceId, IDictionary<string, string> parameters, decimal amount, SourcePayerType? payer, UserDto userDto);

        /// <summary>
        /// 代理商尝试支付
        /// </summary>
        /// <param name="appType">引用类型</param>
        /// <param name="orderType">订单类型</param>
        /// <param name="subject">交易订单标题</param>
        /// <param name="referenceNumber">唯一参考号(代理商id)</param>
        /// <param name="osType">操作系统</param>
        /// <param name="deviceType">设备类型</param>
        /// <param name="deviceId">设备编号</param>
        /// <param name="parameters">参数</param>
        /// <param name="amount">支付金额</param>
        /// <param name="payer">付款方</param>
        /// <param name="admin">管理员</param>
        /// <returns></returns>
        PaymentDto AgentTryPay(SourceAppType appType, FlowType orderType, string subject, string referenceNumber,
            SourceOSType osType, SourceDeviceType deviceType, string deviceId, IDictionary<string, string> parameters,
            decimal amount, SourcePayerType? payer, AdminDto admin);
        /// <summary>
        /// 生成付款码。
        /// </summary>
        /// <param name="appType">应用类型。</param>
        /// <param name="orderType">订单类型。</param>
        /// <param name="subject">交易订单标题</param>
        /// <param name="referenceNumber">唯一参考号。</param>
        /// <param name="osType">操作系统。</param>
        /// <param name="deviceType">设备类型。</param>
        /// <param name="deviceId">设备编号。</param>
        /// <param name="parameters">参数。</param>
        /// <param name="amount">支付金额。</param>
        /// <param name="payer">付款方</param>
        /// <param name="userDto"></param>
        /// <returns></returns>
        PaymentQRCodeDto GenerateQRCode(SourceAppType appType, FlowType orderType, string subject, string referenceNumber, SourceOSType osType, SourceDeviceType deviceType, string deviceId, IDictionary<string, string> parameters, decimal amount, SourcePayerType? payer, UserDto userDto);

        /// <summary>
        /// 代理商生成付款码
        /// </summary>
        /// <param name="appType">应用类型。</param>
        /// <param name="orderType">订单类型。</param>
        /// <param name="subject">交易订单标题</param>
        /// <param name="referenceNumber">唯一参考号。</param>
        /// <param name="osType">操作系统。</param>
        /// <param name="deviceType">设备类型。</param>
        /// <param name="deviceId">设备编号。</param>
        /// <param name="parameters">参数。</param>
        /// <param name="amount">支付金额。</param>
        /// <param name="payer">付款方</param>
        /// <param name="admin">管理员信息</param>
        /// <returns></returns>
        PaymentQRCodeDto AgentGenerateQRCode(SourceAppType appType, FlowType orderType, string subject,
            string referenceNumber, SourceOSType osType, SourceDeviceType deviceType, string deviceId, 
            IDictionary<string, string> parameters, decimal amount, SourcePayerType? payer, AdminDto admin);

        /// <summary>
        /// 退款。
        /// </summary>
        /// <param name="adminId">操作人Id</param>
        /// <param name="adminFullName">操作人姓名</param>
        /// <param name="recordId">唯一参考号。</param>
        /// <param name="refundAmount">退款金额。</param>
        /// <returns>返回剩余的金额。</returns>
        decimal Refund(long adminId, string adminFullName, long recordId, decimal refundAmount);

        /// <summary>
        /// 提现转账
        /// </summary>
        /// <param name="appType">app来源类型</param>
        /// <param name="osType">系统类型</param>
        /// <param name="recordId">记录ID</param>
        /// <param name="transferAmount">转账金额</param>
        /// <param name="userId">用户编号</param>
        /// <param name="open_userid">开放平台用户唯一标识</param>
        /// <param name="userDto"></param>
        /// <returns></returns>
        decimal Transfer(SourceAppType appType, SourceOSType osType, long recordId, decimal transferAmount, long userId, string open_userid,UserDto userDto);

        /// <summary>
        /// 接收通知。
        /// </summary>
        /// <param name="parameters">通知参数。</param>
        /// <param name="paymentDto">支付信息</param>
        /// <returns>返回表示处理成功后需要给通知方返回的结果。</returns>
        ReceiveNotificationDto ReceiveNotification(IDictionary<string, string> parameters, out PaymentDto paymentDto);

        /// <summary>
        /// 同步回调验签--例如支付充值余额
        /// </summary>
        /// <param name="parameters">验签参数</param>
        /// <returns></returns>
        PaymentRecordDto SyncCheckSign(IDictionary<string, string> parameters);

        /// <summary>
        /// 创建App授权登录
        /// </summary>
        /// <param name="appType">App类型</param>
        /// <param name="osType">操作系统类型</param>
        /// <param name="userDto"></param>
        /// <returns></returns>
        IDictionary<string, string> CreateAppAuthLogin(SourceAppType appType, SourceOSType osType, UserDto userDto);

        /// <summary>
        /// 授权登录信息
        /// </summary>
        /// <param name="auth_code">授权码</param>
        /// <param name="appType">App类型</param>
        /// <param name="osType">操作系统类型</param>
        /// <param name="userDto"></param>
        /// <returns></returns>
        IDictionary<string, object> AuthLoginInfo(string auth_code, SourceAppType appType, SourceOSType osType, UserDto userDto);

        /// <summary>
        /// 同步付款状态，针对同一订单仅允许执行一次。
        /// </summary>
        /// <param name="paymentRecordId">支付记录编号。</param>
        /// <param name="requestDto">同步请求参数。</param>
        /// <returns></returns>
        PaymentRecordDto Synchronize(long paymentRecordId, PaymentSynchronizeRequestDto requestDto);
    }
}
